第 5 章:使用 Handlers 觸發機制
Handlers 是什麼
Handlers 是我們在 Ansible Playbooks 裡很常用來重開系統服務 (Service) 的手法,Handler 本身是一種非同步的 callback function ;在這裡則是指關連於特定 tasks 的事件 (event) 觸發機制。當這些特定的 tasks 狀態為被改變 (changed) 且都已被執行時,才會觸發一次 event。
要觸發 restart nginx
這個 handler,需符合以下條件:
modify index.html
或turn server_tokens off
兩個 tasks 中,至少有一個狀態為 changed- 所有關連到
restart nginx
handler 的 tasks 都已被執行
怎麼使用 Handlers
建立 ansible.cfg
vi ansible.cfg
[defaults]
inventory = inventory
remote_user = docker
private_key_file = ~/.ssh/id_rsa
host_key_checking = False
retry_files_save_path = ./ansible-retry
建立 inventory file
vi inventory
server1 ansible_ssh_host=192.168.1.104 ansible_ssh_port=2221
建立 setup_nginx.yml
vi setup_nginx.yml
---
- name: setup the nginx
hosts: all
become: true
vars:
username: "ironman"
mail: "chusiang (at) drx.tw"
blog: "http://note.drx.tw"
tasks:
# 執行 'apt-get update' 指令。
- name: update apt repo cache
apt: name=nginx update_cache=yes
# 執行 'apt-get install nginx' 指令。
- name: install nginx with apt
apt: name=nginx state=present
# 於網頁根目錄 (DocumentRoot) 編輯 index.html。
- name: modify index.html
template: >
src=templates/index.html.j2
dest=/usr/share/nginx/html/index.html
owner=www-data
group=www-data
mode="644"
backup=yes
notify: restart nginx
# (security) 關閉 server_tokens:移除 server_tokens 前的 '#' 字元。
- name: turn server_tokens off
lineinfile: >
dest=/etc/nginx/nginx.conf
regexp="server_tokens off;"
insertafter="# server_tokens off;"
line="server_tokens off;"
state=present
notify: restart nginx
# handlers
#
# 當確認事件有被觸發才會動作。
# 一個 handler 可被多個 task 通知 (notify),並於 tasks 跑完才會執行。
handlers:
# 執行 'sudo service nginx restart' 指令。
- name: restart nginx
service: name=nginx enabled=yes state=restarted
# post_tasks:
#
# 在 tasks 之後執行的 tasks。
post_tasks:
# 檢查網頁內容。
- name: review http state
command: "curl -shttp://localhost"
register: web_context
# 印出檢查結果。
- name: print http state
debug: msg={{ web_context.stdout_lines }}
# vim:ft=ansible :
- 在第 47 行裡,我們建立了一個
restart nginx
handler。 - 在修改到 Nginx 設定檔的 tasks (
modify index.html
,turn server_tokens off
) 裡,使用notify
通知 handlers (restart nginx
) 說這些 Tasks 要進行關連。 - 最後在
post_tasks
裡建了 2 個 tasks,讓它們可以在一般的 tasks 結束後才執行。
mkdir templates && vi templates/index.html.j2
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Day15 demo | automate-with-ansible</title>
</head>
<style type="text/css" media="all">
body {
font-size: x-large;
}
</style>
<body>
<p>
<pre>[ {{ username }}@automate-with-ansible ~ ]$ hostname
automate-with-ansible.drx.tw
[ {{ username }}@automate-with-ansible ~ ]$ cowsay "This is a ansible-playbook demo for automate-with-ansible at 2016/12/15."
_____________________________________
/ This is a ansible-playbook demo for \
\ automate-with-ansible at 2016/12/15./
-------------------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
[ {{ username }}@automate-with-ansible ~ ]$
[ {{ username }}@automate-with-ansible ~ ]$
[ {{ username }}@automate-with-ansible ~ ]$ cat .profile
- {{ mail }}
- {{ blog }}</pre>
</p>
</body>
</html>
- 在這份 index.html.j2 裡,我們用了
username
,mail
和blog
三個變數,其值會從setup_nginx.yml
中代入 - 執行 Playbook。
- 試著多跑幾次,就會發現當
modify index.html
和turn server_tokens off
tasks 的狀態不為 changed 時,該 handler 不會被觸發的差異 - 在此例中,我們可以藉由修改 Playbook 裡的變數 (vars) 來重複觸發 handler,例如把
username
從ironman
修改成root
- 試著多跑幾次,就會發現當